package com.smartboard.network.server;

import com.smartboard.network.game.IPlayGame;
import com.smartboard.network.game.IRoom;
import com.smartboard.network.game.IUser;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by cheas on 2018/8/13.
 */

public class PlayGame implements IPlayGame, Serializable {
    private static final long serialVersionUID = 2L;

    private int mId;
    private IRoom mRoom;
    private String mName;
    private IUser mOwner;
    private Object mGameInfo;

    private IUser mPlayer1;
    private IUser mPlayer2;

    private List<IUser> mWatchers;

    private IUser mNextPlayer;

    private int mGameState = STATE_NOT_START;
    private IUser mWinner;
    private int mResult;

    private PlayGame() {

    }

    public PlayGame(IRoom room, String name, IUser owner, Object gameInfo) {
        mRoom = room;
        mName = name;
        mGameInfo = gameInfo;
        mId = IdsPool.createId(IdsPool.ID_TYPE_GAME, owner.getChessType());
        mWatchers = new ArrayList<>();
        IdsPool.addObject(mId, this);
    }

    public void joinGame(IUser user) {
        if(mPlayer1 == null) {
            mPlayer1 = user;
            if(mWatchers.contains(user))
                mWatchers.remove(user);
        } else if(mPlayer2 == null) {
            mPlayer2 = user;
            if(mWatchers.contains(user))
                mWatchers.remove(user);
        } else {

            mWatchers.add(user);
        }
        ((User)user).setGameId(mId);
    }

    // return true--escape, false--just leave
    public boolean quitGame(IUser user) {
        boolean escape = false;
        if(mPlayer1.equals(user) || mPlayer2.equals(user)) {
            if(mGameState == STATE_PLAYING) {
                setGameState(STATE_NOT_START);
                escape = true;
            }
            if(mPlayer1.equals(user))
                mPlayer1 = null;
            else
                mPlayer2 = null;
        } else if(mWatchers.contains(user)) {
            mWatchers.remove(user);
        }
        ((User)user).setGameId(-1);
        return escape;
    }

    @Override
    public Object getGameInfo() {
        return mGameInfo;
    }

    @Override
    public int getId() {
        return mId;
    }

    @Override
    public String getName() {
        return mName;
    }

    public void setName(String name) {
        mName = name;
    }

    @Override
    public IRoom getRoom() {
        return mRoom;
    }

    @Override
    public IUser getOwner() {
        return mOwner;
    }

    @Override
    public IUser getPlayer1() {
        return mPlayer1;
    }

    @Override
    public IUser getPlayer2() {
        return mPlayer2;
    }

    @Override
    public List<IUser> getWatchers() {
        return mWatchers;
    }

    @Override
    public IUser getNextPlayer() {
        if(mGameState != STATE_PLAYING)
            return null;
        return mNextPlayer;
    }

    protected void initNextPlayer(boolean isPlayer2) {
        mNextPlayer = isPlayer2 ? mPlayer2 : mPlayer1;
    }

    protected void changePlayer() {
        if(mNextPlayer == mPlayer1)
            mNextPlayer = mPlayer2;
        else
            mNextPlayer = mPlayer1;
    }

    @Override
    public boolean isInPlaying(IUser user) {
        return mGameState == STATE_PLAYING && (user.equals(mPlayer1) || user.equals(mPlayer2));
    }

    @Override
    public int getGameState() {
        return mGameState;
    }

    @Override
    public int getResult() {
        return mResult;
    }

    public void setResult(int result) {
        mResult = result;
    }

    public void setGameState(int state) {
        if(mGameState == state)
            return;
        mGameState = state;
        if(state != STATE_PLAYING) {
            if(mPlayer1 != null)
                ((User)mPlayer1).setIsReady(false);
            if(mPlayer2 != null)
                ((User)mPlayer2).setIsReady(false);
        }
    }

    @Override
    public IUser getWinner() {
        return mWinner;
    }

    public void setWinner(IUser winer) {
        mWinner = winer;
    }

    public PlayGame clone() {
        PlayGame newGame = new PlayGame();
        newGame.mId = mId;
        newGame.mRoom = mRoom;
        newGame.mName = mName;
        newGame.mOwner = mOwner;
        newGame.mGameInfo = mGameInfo;
        newGame.mPlayer1 = mPlayer1;
        newGame.mPlayer2 = mPlayer2;
        newGame.mWatchers = new ArrayList<>();
        newGame.mWatchers.addAll(mWatchers);
        newGame.mNextPlayer = mNextPlayer;
        newGame.mGameState = mGameState;
        newGame.mWinner = mWinner;
        newGame.mResult = mResult;
        return newGame;
    }

    @Override
    public boolean equals(Object other) {
        return other instanceof PlayGame && mName.equals(((PlayGame) other).mName);
    }

    @Override
    public String toString() {
        return "PlayGame[name=" + mName + "]";
    }
}
